package org.zhangchao.poi.excel.interceptor;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.zhangchao.poi.excel.common.ExcelHeader;
import org.zhangchao.poi.excel.common.template.ExcelTemplateParam;
import org.zhangchao.poi.excel.exception.ExcelException;
import org.zhangchao.poi.util.DateUtil;

/**
 * Excel 解析对象拦截器，将解析的对象对应excle一行
 * 
 * @author zhangchao
 * 
 */
public class ExcelProcessModelHandlerInterceptor implements
		ExcelHandlerInterceptor {

	/** 要解析成的对象类型 */
	private Class<?> clazz;

	/** 存储要解析对象, ExcelHeader集合 */
	private List<ExcelHeader> headerList;
	
	/** 日期转格式*/
	private String dateConverterPattern = "yyyy-mm-dd";
	
	/** data的索引 */
	private int dataIndex;
	
	/** 模板参数 */
	private ExcelTemplateParam etp;

	// public ExcelBuildModelHandlerInterceptor() {
	// super();
	// }

	/**
	 * Excel 构建对象拦截器构造方法
	 * 
	 * @param clazz
	 *            要构建对象的类型
	 */
	public ExcelProcessModelHandlerInterceptor(Class<?> clazz) {
		super();
		if (null == clazz) {
			throw new ExcelException("没有设置要解析对象的类型，设置要解析对象的Class类型");
		}
		this.clazz = clazz;
		if (null == headerList) {
			// 设置映射关系
			headerList = ExcelHeader.buildHeaderList(clazz);
		}
	}

	//@Override
	public void handler(Row row, MakeHandler makeHandler,
			ExcelHandlerInterceptorStack handlerStack) {
		List<?> data = makeHandler.prepareModelData();
		if(null == etp) {
			etp = makeHandler.getExcelTemplateaParam();
		}
		int rowNum = row.getRowNum();
		if(rowNum == 0) {
			//写标题
			createHeaderCell(row);
		}else {
			//写数据
			createDataCell(row, data);
		}
		handlerStack.handler(row, makeHandler, handlerStack);
	}
	
	/**
	 * 
	 * @param row
	 */
	private void createHeaderCell(Row row) {
		int index = 0;
		if(null != etp) {
			index = etp.getInitColIndex();
		}
		for (int i = 0; i < headerList.size(); i++) {
			Cell cell = row.createCell(i + index);
			cell.setCellValue(headerList.get(i).getColumnTitle());
			if (null != etp) {
				Map<Integer, CellStyle> cellStyles = etp.getStyles();
				CellStyle defaultStyle = etp.getDefaultStyle();
				if (cellStyles.containsKey(i + index)) {
					cell.setCellStyle(cellStyles.get(i + index));
				} else if(null != defaultStyle){
					cell.setCellStyle(defaultStyle);
				}
			}
		}
	}

	/**
	 * 
	 * @param row
	 */
	private void createDataCell(Row row,List<?> data) {
			int index = 0;
			if(null != etp) {
				index = etp.getInitColIndex();
			}
			Object obj = data.get(dataIndex++);
			for (int i = 0; i < headerList.size(); i++) {
				ExcelHeader excelHeader = headerList.get(i);
				String fieldName = excelHeader.getFieldName();
				Cell cell= row.createCell(i + index);
				if (null != etp) {
					Map<Integer, CellStyle> cellStyles = etp.getStyles();
					CellStyle defaultStyle = etp.getDefaultStyle();
					if (null != cellStyles && cellStyles.containsKey(i + index)) {
						cell.setCellStyle(cellStyles.get(i + index));
					} else if(null != defaultStyle){
						cell.setCellStyle(defaultStyle);
					}
				}
				try {
					Object objFieldValue = PropertyUtils.getProperty(obj, fieldName);
					//如果是Date类型
					if(objFieldValue.getClass().equals(Date.class)) {
						String pattern = dateConverterPattern;
						if(null != excelHeader.getDatePattern()) {
							pattern = excelHeader.getDatePattern();
						}
						cell.setCellValue(DateUtil.format((Date)objFieldValue, pattern));
					}else {
						cell.setCellValue(BeanUtils.getProperty(obj, fieldName));
					}
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				}
			}
	}

	public Class<?> getClazz() {
		return clazz;
	}

	public void setClazz(Class<?> clazz) {
		this.clazz = clazz;
	}

	public List<ExcelHeader> getHeaderList() {
		return headerList;
	}

	public void setHeaderList(List<ExcelHeader> headerList) {
		this.headerList = headerList;
	}

	public String getDateConverterPattern() {
		return dateConverterPattern;
	}

	public void setDateConverterPattern(String dateConverterPattern) {
		this.dateConverterPattern = dateConverterPattern;
	}
	
}
